#include "evm_stack.h"
#include "evm_error.h"

#include <stdlib.h>
#include <stdio.h>

evm_stack* evm_stack_new  ( uint32_t size ) {
    evm_stack *s = (evm_stack*)malloc( sizeof( evm_stack ) );
    if ( s ) {
        s->data =  (uint32_t*)malloc( size * sizeof( uint32_t ) );
        if ( s->data ) {
            s->allocated = size;
            s->sp        = s->data;
            s->size      = 0;
        } else {
            free( s );
            s = 0;
        }
    }

    return s;
}


void  evm_stack_free ( evm_stack* st ) {
    if ( st ) {
        if ( st->data ) {
            free( st->data );
        }
        free( st );
    }
}



inline uint32_t evm_stack_push( evm_stack* st, uint32_t  value ) {
    if ( st ) {
        if ( st->size < st->allocated ) {
            *st->sp   = value;
            st->sp   += 1;
            st->size += 1;
            return EVM_OK;
        } else {
            return ERR_STACK_OVERFLOW;
        }
    } else {
        return ERR_NULLPTR;
    }
}



inline uint32_t evm_stack_pop ( evm_stack* st, uint32_t *value ) {
    if ( st ) {
        if ( st->size > 0 ) {
            st->sp   -= 1;
            st->size -= 1;
            if ( value ) {
                *value    = *st->sp;
            }
            return EVM_OK;
        } else {
            return ERR_STACK_UNDERFLOW;
        }
    } else {
        return ERR_NULLPTR;
    }
}
